import fcntl
from commons import executeCommand

class CriticalSectionLock(object):

    def __init__(self, filename):
        try:
            self.filename = filename
            # This will create it if it does not exist already
            self.handle = open(self.filename, 'w')
            cmd = "/usr/bin/sudo /bin/chmod 777 " + self.filename
            executeCommand(cmd, [], True)
        except:
            raise

    # flock() is a blocking call unless it is bitwise ORed with LOCK_NB to avoid blocking 
    # on lock acquisition.  This blocking is what I use to provide atomicity across forked
    # Django processes since native python locks and semaphores only work at the thread level
    def acquire(self):
        try:
            fcntl.flock(self.handle, fcntl.LOCK_EX|fcntl.LOCK_NB)
        except:
            raise

    def release(self):
        try:
            fcntl.flock(self.handle, fcntl.LOCK_UN)
            cmd = "/usr/bin/sudo /bin/rm -f " + self.filename
            executeCommand(cmd, [], True)
            return True
        except:
            return False

    def __del__(self):
        try:
            self.handle.close()
        except:
            pass
